#include "Ordinary.h"
#include "HistoryManager.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <gio/giotypes.h>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <thread>
#include <vector>
#include <string.h>

#include <genai/text/chat.h>

struct Ordinary::Impl
{
    GMainLoop *loop = nullptr;
    GenAiTextSession *session = nullptr;
    ChatModelConfig *config = nullptr;
    HistoryManager *historyManager = nullptr;

    static std::string userQuery; // 用户新的提问，用来装入历史记录的
                                  // 没有模型回答是因为可以用output_text来代替

    static std::string finish_reason;
    static std::string output_buffer;
    static std::string output_text;
    static std::string stop_chat_flag; //阻止继续打印模型输出的，防止打印乱码

    // static std::string end_flag; // 结束标识符，用来判断是否一轮聊天结束


    static void callback(ChatResult *result, void *user_data)
    {

        HistoryManager interimHM; //临时的用一用，这里没法子了

        auto getBool = [](bool value) {return value ? "true" : "false"; };

        const char *message = chat_result_get_assistant_message(result);
        const char *reason = chat_result_get_finish_reason_message(result);
        std::string  is_end = getBool(chat_result_get_is_end(result));

        // std::lock_guard<std::mutex> lock(mtx); //加锁防止对output_text的读写冲突,当然这里有个bug解决不了，bug是下面写文件的过程，如果在写的过程中打开这个历史记录就会出问题
        
        // end_flag = is_end; // 结束标识符，用来判断是否一轮聊天结束，得放在加锁的后面

        if (is_end == "false") {
            output_buffer += message;

        } else if (is_end == "true" && stop_chat_flag != "end") {
            output_buffer += message;
            output_text = output_buffer;
            std::cout << "模型回答: " << output_text<< std::endl;

            // std::cout << userQuery;
            interimHM.saveTurn(userQuery, output_text, "../conversations/history.json");
            userQuery = ""; // 记录完成后清空userQuery，准备接受下一个用户的提问

            output_buffer = "";
            output_text = "";

            finish_reason = reason;
        } else {

        }

        // std::cout << "模型回答: " << (message ? message : "(null)") << std::endl;
        // std::cout << "结束原因: " << (reason ? reason : "(null)") << std::endl;
        // std::cout << "是否完成: " << (is_end == "true" ? "yes" : "no") << std::endl;
    }

    Impl()
    {

        historyManager = new HistoryManager();

        historyManager->createHistoryFile("../conversations/history.json");//先创建临时的，后面模型对话结束后改名

        loop = g_main_loop_new(nullptr, FALSE);
        std::thread eventThread([this]()
                                {
            g_main_loop_run(loop);
            g_main_loop_unref(loop); });
        eventThread.detach();//把当前线程放到后台成为守护线程，在主线程结束时，守护线程不会跟随主线程一起结束。

        // 1. 创建并设置模型配置
        config = chat_model_config_create();
        if (!config)
        {
            fprintf(stderr, "Failed to create model config\n");
            genai_text_destroy_session(&session);

        }

        chat_model_config_set_name(config, "Qwen-2.5-3b_1.0");
        chat_model_config_set_top_k(config, 0.5);

        // 使用云端模型
        // chat_model_config_set_deploy_type(config, ModelDeployType::PublicCloud);

        // 使用端侧模型
        chat_model_config_set_deploy_type(config, ModelDeployType::OnDevice);

        // 2. 创建会话
        session = genai_text_create_session();
        if (!session)
        {
            fprintf(stderr, "Failed to create session\n");

        }
        
        // 在会话建立后设置模型配置
        genai_text_set_model_config(session, config);


        // 3. 初始化会话
        if (genai_text_init_session(session) != 0)
        {
            fprintf(stderr, "Failed to initialize session\n");
            genai_text_destroy_session(&session);

        }

        // 4. 设置系统提示词（可以用 set_c(message ? message : "(null)") hat_system_prompt_id 选择内置提示词）
        genai_text_set_chat_system_prompt(session, "你是一个聪明的AI助手。");

        // 5. 设置回调函数
        genai_text_result_set_callback(session, callback, NULL); // 注册回调函数

    }

    ~Impl()
    {
        if (historyManager){
            delete historyManager;
        }
        if (session)
        {
            genai_text_stop_chat(session);
            genai_text_destroy_session(&session);
        }
        if (loop)
        {
            g_main_loop_quit(loop);
        }

        if (config)
        {
            chat_model_config_destroy(&config);
        }

        // if () {

        // }
    }

    void send(const std::string &msg)
    {
        userQuery = msg; // 做做记录，用来装入历史记录的
        // std::cout <<userQuery<<"123\n";
        genai_text_chat_async(session, msg.c_str());
    }
};

// 在类外定义并初始化静态成员

std::string Ordinary::Impl::userQuery = "";

std::string Ordinary::Impl::output_buffer = "";
std::string Ordinary::Impl::output_text = "";
std::string Ordinary::Impl::finish_reason = "";
std::string Ordinary::Impl::stop_chat_flag = "";

Ordinary::Ordinary() : pImpl(new Impl) {}
Ordinary::~Ordinary() { delete pImpl; }


//让用户输入exit后退出模型，确保callback最后一次调用的时候不会输出那个 "模型回答: "………… 这个部分
void Ordinary::setChatFlag(std::string flag){
    pImpl->stop_chat_flag = flag;
}

void Ordinary::sendMessage(const std::string &message)
{
    pImpl->send(message);
}

// //加锁防止对output_text的读写冲突
// std::string Ordinary::getResponse(){
//     std::lock_guard<std::mutex> lock(mtx);
//     if (pImpl->output_text != "" && pImpl->end_flag == "true"){//一轮对话完成的时候执行，前面的部分由于执行速度的原因，可能还没来得及写入内容，所以得加
//         return pImpl->output_text;
//     } else {
//         return "";
//     }
    
// }